﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Threading;

namespace CPN.PJN.Silverlight.UI.Controls
{
    /// <summary>
    /// Popup de notification
    /// </summary>
    [TemplatePart(Name = NotificationPopup.RootElementName, Type = typeof(Grid))]
    [TemplateVisualState(Name = VisualStateHelper.StateNormal, GroupName = VisualStateHelper.GroupCommon)]
    [TemplateVisualState(Name = VisualStateHelper.StateMouseOver, GroupName = VisualStateHelper.GroupCommon)]
    [TemplateVisualState(Name = NotificationPopup.GroupNotification, GroupName = NotificationPopup.StateShow)]
    [TemplateVisualState(Name = NotificationPopup.GroupNotification, GroupName = NotificationPopup.StateHide)]
    public class NotificationPopup : Control
    {
        #region Constants

        private const string RootElementName = "Root";

        private const string GroupNotification = "NotificationStates";
        private const string StateShow = "Show";
        private const string StateHide = "Hide";

        #endregion

        #region Membres


        #region ShowDuration (DependencyProperty)

        /// <summary>
        /// Durée d'affichage du message
        /// </summary>
        public double ShowDuration
        {
            get { return (double)GetValue(ShowDurationProperty); }
            set { SetValue(ShowDurationProperty, value); }
        }
        public static readonly DependencyProperty ShowDurationProperty =
            DependencyProperty.Register("ShowDuration", typeof(double), typeof(NotificationPopup),
            new PropertyMetadata(5d, new PropertyChangedCallback(OnShowDurationChanged)));

        private static void OnShowDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((NotificationPopup)d).OnShowDurationChanged(e);
        }

        protected virtual void OnShowDurationChanged(DependencyPropertyChangedEventArgs e)
        {
            InitTimer();
        }

        #endregion


        #region Message (DependencyProperty)

        /// <summary>
        /// Message
        /// </summary>
        public string Message
        {
            get { return (string)GetValue(MessageProperty); }
            set { SetValue(MessageProperty, value); }
        }
        public static readonly DependencyProperty MessageProperty =
            DependencyProperty.Register("Message", typeof(string), typeof(NotificationPopup),
            new PropertyMetadata(string.Empty, null));

        #endregion

        #endregion Membres

        /// <summary>
        /// Evénement soulevé lorsque la notification est cachée
        /// </summary>
        public EventHandler NotificationCompleted;
        
        private DispatcherTimer timer;

        #region Constructeurs
        /// <summary>
        /// Ce contrôle est utilisé pour afficher un message
        /// </summary>
        public NotificationPopup()
        {
            DefaultStyleKey = typeof(NotificationPopup);
        }

        #endregion Constructeurs

        #region Initialisation

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            Grid root = GetTemplateChild(RootElementName) as Grid;

            Storyboard hideStoryboard = root.FindStoryboard(GroupNotification, StateHide);
            hideStoryboard.Completed += new EventHandler(Hide_Completed);

            Show();
        }

        void InitTimer()
        {
            if (timer == null)
            {
                timer = new DispatcherTimer();
                timer.Tick += new EventHandler(timer_Tick);
            }

            timer.Stop();
            timer.Interval = TimeSpan.FromSeconds(ShowDuration);
            timer.Start();
        }

        #endregion

        #region Evénements

        void Hide_Completed(object sender, EventArgs e)
        {
            if (NotificationCompleted != null)
            {
                NotificationCompleted(this, EventArgs.Empty);
            }
        }

        void timer_Tick(object sender, EventArgs e)
        {
            Hide();
        }

        #endregion Evénements

        #region Méthodes

        /// <summary>
        /// Affiche la notification
        /// </summary>
        public void Show()
        {
            VisualStateManager.GoToState(this, StateShow, true);
            
            InitTimer();

            this.MouseLeftButtonDown += new MouseButtonEventHandler(PopupNotification_MouseLeftButtonDown);
        }

        /// <summary>
        /// Cache la notification
        /// </summary>
        public void Hide()
        {
            timer.Stop();

            VisualStateManager.GoToState(this, StateHide, true);

            this.MouseLeftButtonDown -= new MouseButtonEventHandler(PopupNotification_MouseLeftButtonDown);
        }

        void PopupNotification_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Hide();
        }

        #endregion Méthodes

    }
}
